package gamer2;

import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;

import utils.Vec;


public class GLTools {
	private Vec m_camera = null;
	private Vec m_target = null;
	public double perspective = 60;
	public double aspect_ratio = 4.0f / 3.0f;
	private double pm[] = new double[16]; // to get viewport matrix

	double matrix2[] = new double[16];
	double resultMatrix[] = new double[16];
	Vec side = new Vec();
	Vec up = new Vec();

	private Vec m_light = new Vec(0, 1, 0);
	public Vec m_lookup;

	public int m_width, m_height;
	public GL2 m_gl = null;

	public GLU m_glu = new GLU();

	public GLTools(GL2 gl, int w, int h, final Vec c, final Vec t, final Vec l) {
		m_gl = gl;
		m_width = w;
		m_height = h;
		m_lookup = l;
		m_target = t;
		m_camera = c;
		aspect_ratio = (float) w / (float) h;
	}

	public void setCamera(final double x, final double y, final double z) {
		m_camera.set(x, y, z);
	}

	public void setLight(final double x, final double y, final double z) {
		m_light.set(x, y, z);
	}

	public void setTarget(final double x, final double y, final double z) {
		m_target.set(x, y, z);
	}

	public void setLookup(final double x, final double y, final double z) {
		m_lookup.set(x, y, z);
	}

	public Vec getCamera() {
		return m_camera;
	}

	public Vec getTarget() {
		return m_target;
	}

	public Vec getLight() {
		return m_light;
	}

	public void setupCamera() {

		m_gl.glLoadIdentity();
		// m_lookup.set(0,1,0);
/*		m_glu.gluLookAt(getCamera().x() , getCamera().y(), getCamera().z(),
				getTarget().x(), getTarget().y(), getTarget().z(),
				m_lookup.x(), m_lookup.y(), m_lookup.z());
*/
		/*Vec m = Settings.settings.globalVariables.Modifier;
		m_glu.gluLookAt(getCamera().x() - m.x() , getCamera().y()-m.y(), getCamera().z()-m.z(),
				getTarget().x()-m.x(), getTarget().y()-m.y(), getTarget().z()-m.z(),
				m_lookup.x(), m_lookup.y(), m_lookup.z());*/
}

	/*
	 * private void glhLookAtf2( double[] matrix, Vec Camera, Vec Target, Vec up
	 * ) { //------------------
	 * 
	 * NormalizeVector(forward); //------------------ //Side = forward x up
	 * side.cross(Target, up); side.normDirect(); //------------------
	 * //Recompute up as: up = side x forward ComputeNormalOfPlane(up, side,
	 * forward); up.cross(side, Target);
	 * 
	 * //------------------ matrix2[0] = side.x(); matrix2[4] = side.y();
	 * matrix2[8] = side.z(); matrix2[12] = 0.0; //------------------ matrix2[1]
	 * = up.x(); matrix2[5] = up.y(); matrix2[9] = up.z(); matrix2[13] = 0.0;
	 * //------------------ matrix2[2] = -Target.x(); matrix2[6] = -Target.y();
	 * matrix2[10] = -Target.z(); matrix2[14] = 0.0; //------------------
	 * matrix2[3] = matrix2[7] = matrix2[11] = 0.0; matrix2[15] = 1.0;
	 * //------------------
	 * 
	 * 
	 * MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2);
	 * glhTranslatef2(resultMatrix, -eyePosition3D[0], -eyePosition3D[1],
	 * -eyePosition3D[2]); //------------------ memcpy(matrix, resultMatrix,
	 * 16*sizeof(float)); }
	 */
	public void setPerspective(double p, double near, double far) {
		perspective = p;
		m_gl.glMatrixMode(GL2.GL_PROJECTION);
		m_gl.glLoadIdentity();
		aspect_ratio = 1.0f * m_width / (double) (m_height);
		m_glu.gluPerspective(p, aspect_ratio, near, far);
		m_gl.glMatrixMode(GL2.GL_MODELVIEW);
	}

	Vec coord2ray(double px, double py) {
		double P = perspective / 360.0 * 2 * 3.14159; // convert to radians
		Vec res = new Vec();
		Vec dir = new Vec();
		double x = px + m_width / 2;
		double y = py + m_height / 2;
		// modifiers
		double mmx = Math.tan(P * 0.5) * (1.0 - (x * 2) / (double) m_width)
				* aspect_ratio;
		double mmy = Math.tan(P * 0.5) * -(1.0 - (y * 2) / (double) m_height);

		// find position in viewspace
		dir.set((double) mmx, (double) mmy, 1.0f);
		m_gl.glGetDoublev(GL2.GL_MODELVIEW_MATRIX, pm, 0);
		dir.glMatMul(res, pm);
		res.normDirect();
		return res;

		/*
		 * double pm[16]; // to get viewport matrix Vector res, dir; double x =
		 * px + width/2; double y = py + height/2; // modifiers double mmx =
		 * tan(P*0.5)*(1.0-(x*2)/(double)width)*aspect_ratio; double mmy =
		 * tan(P*0.5)*-(1.0-(y*2)/(double)height);
		 * 
		 * glGetdoublev(GL_MODELVIEW_MATRIX, pm); // find position in viewspace
		 * dir = Vector(mmx,mmy,1); res = (dir.glMatMul(pm)).Normalize();
		 */

	}

	public void screenToTexture(final CTexture texture) {

		m_gl.glEnable(GL2.GL_TEXTURE_2D);
		texture.Enable(m_gl);
//		 m_gl.glTexParameterf( GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
		// );
//				 m_gl.glTexParameterf( GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
		// );
//		System.out.println(m_width);
/*		m_gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, 0, 0, m_width,
				m_height, 0);*/
		float s = 1f; // 0.95
		m_gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, 0, 0, (int)(s*m_width),
				(int)(m_height*s), 0);
	}

	public void RenderOrthoScreen() {
		SetOrthographicProjection();

		m_gl.glLoadIdentity();
		m_gl.glPushMatrix();

		m_gl.glDisable(GL2.GL_DEPTH_TEST);
		// m_gl.glEnable(GL2.GL_TEXTURE_2D);
		m_gl.glDisable(GL2.GL_FOG);
		m_gl.glDisable(GL2.GL_CULL_FACE);
		m_gl.glDisable(GL2.GL_BLEND);

		m_gl.glColor4f(1, 1, 1, 1);

		m_gl.glBegin(GL2.GL_QUADS);
		m_gl.glTexCoord2d(0.0, 1.0);
		m_gl.glVertex3f(0, 0, 0);

		m_gl.glTexCoord2d(1.0, 1.0);
		m_gl.glVertex3f(m_width, 0, 0);
		m_gl.glTexCoord2d(1.0, 0.0);
		m_gl.glVertex3f(m_width, m_height, 0);
		m_gl.glTexCoord2d(0.0, 0.0);
		m_gl.glVertex3f(0, m_height, 0);
		m_gl.glEnd();

		m_gl.glPopMatrix();

		ResetPerspectiveProjection();

		m_gl.glDisable(GL2.GL_TEXTURE_2D);
		m_gl.glEnable(GL2.GL_DEPTH_TEST);
		m_gl.glEnable(GL2.GL_CULL_FACE);

	}

	public void SetOrthographicProjection() {

		m_gl.glMatrixMode(GL2.GL_PROJECTION);
		m_gl.glPushMatrix();
		m_gl.glLoadIdentity();
		m_glu.gluOrtho2D(0, m_width, 0, m_height);
		m_gl.glScalef(1, -1, 1);
		m_gl.glTranslatef(0, -m_height, 0);
		//m_gl.glTranslatef(+m_width/2, -m_height,m_height/2);
			m_gl.glMatrixMode(GL2.GL_MODELVIEW);
	}

	public void ResetPerspectiveProjection() {
		m_gl.glMatrixMode(GL2.GL_PROJECTION);
		m_gl.glPopMatrix();
		m_gl.glMatrixMode(GL2.GL_MODELVIEW);
	}

}
